/**
 * @file user_repository.h
 * @brief 用户数据访问层 - 负责用户数据的CRUD操作和缓存管理
 * @author 29108
 * @date 2025/7/21
 * @version 1.0
 *
 * 功能特性:
 * - 用户基础信息的数据库操作
 * - 游戏用户数据的管理
 * - 智能缓存策略（Redis）
 * - 批量操作优化
 * - 事务支持
 * - 连接池管理
 *
 * 性能特性:
 * - 读写分离支持
 * - 缓存预热和失效
 * - 批量查询优化
 * - 异步操作支持
 * - 连接池复用
 *
 * 与现有模块集成:
 * - 使用MySQL连接池进行数据库操作
 * - 使用Redis连接池进行缓存管理
 * - 使用ThreadPool进行异步处理
 * - 使用ConfigManager进行配置管理
 * - 使用Logger进行日志记录
 */

#ifndef USER_REPOSITORY_H
#define USER_REPOSITORY_H

#include "user_models.h"
#include "common/database/mysql_pool.h"
#include "common/database/redis_pool.h"
#include "common/thread_pool/thread_pool.h"
#include "common/config/config_manager.h"
#include "common/logger/logger.h"
#include <string>
#include <vector>
#include <optional>
#include <memory>
#include <future>
#include <chrono>
#include <atomic>
#include <unordered_map>
#include <nlohmann/json.hpp>

// MySQL Connector/C++ 前向声明
namespace sql {
    class ResultSet;
}

namespace core_services {
    namespace auth_service {

        /**
         * @brief 查询条件结构体
         */
        struct QueryCondition {
            std::string field;                                      ///< 字段名
            std::string operator_;                                  ///< 操作符（=, !=, >, <, >=, <=, LIKE, IN）
            std::string value;                                      ///< 值
            std::string logic_operator = "AND";                     ///< 逻辑操作符（AND, OR）

            /**
             * @brief 构造函数
             * @param field 字段名
             * @param operator_ 操作符
             * @param value 值
             * @param logic_operator 逻辑操作符
             */
            QueryCondition(const std::string& field, const std::string& operator_,
                          const std::string& value, const std::string& logic_operator = "AND");
        };

        /**
         * @brief 查询选项结构体
         */
        struct QueryOptions {
            std::vector<QueryCondition> conditions;                 ///< 查询条件
            std::string order_by;                                   ///< 排序字段
            std::string order_direction = "ASC";                    ///< 排序方向（ASC, DESC）
            int limit = 0;                                          ///< 限制数量（0表示无限制）
            int offset = 0;                                         ///< 偏移量
            bool use_cache = true;                                  ///< 是否使用缓存
            std::chrono::seconds cache_ttl{3600};                   ///< 缓存TTL（默认1小时）

            /**
             * @brief 添加查询条件
             * @param condition 查询条件
             */
            void addCondition(const QueryCondition& condition);

            /**
             * @brief 构建WHERE子句
             * @return WHERE子句字符串
             */
            std::string buildWhereClause() const;
        };

        /**
         * @brief 批量操作结果
         */
        struct BatchOperationResult {
            bool success = false;                                   ///< 操作是否成功
            int affected_rows = 0;                                  ///< 影响的行数
            std::vector<std::string> errors;                        ///< 错误信息列表
            std::chrono::milliseconds execution_time{0};            ///< 执行时间

            /**
             * @brief 默认构造函数
             */
            BatchOperationResult() = default;

            /**
             * @brief 成功结果构造函数
             * @param affected_rows 影响的行数
             * @param execution_time 执行时间
             */
            BatchOperationResult(int affected_rows, std::chrono::milliseconds execution_time);

            /**
             * @brief 失败结果构造函数
             * @param errors 错误信息列表
             */
            explicit BatchOperationResult(const std::vector<std::string>& errors);
        };

        /**
         * @brief 用户数据访问层类
         * @details 负责用户数据的完整生命周期管理
         */
        class UserRepository {
        public:
            /**
             * @brief 配置结构体
             */
            struct Config {
                bool enable_cache = true;                           ///< 是否启用缓存
                std::chrono::seconds default_cache_ttl{3600};       ///< 默认缓存TTL（1小时）
                std::chrono::seconds user_cache_ttl{1800};          ///< 用户信息缓存TTL（30分钟）
                std::chrono::seconds game_data_cache_ttl{600};      ///< 游戏数据缓存TTL（10分钟）
                bool enable_read_write_split = false;               ///< 是否启用读写分离
                int max_batch_size = 1000;                          ///< 最大批量操作大小
                bool enable_async_operations = true;                ///< 是否启用异步操作
                int connection_timeout_seconds = 30;                ///< 连接超时时间
                int query_timeout_seconds = 60;                     ///< 查询超时时间

                /**
                 * @brief 从配置管理器加载配置
                 * @return 用户仓库配置对象
                 */
                static Config fromConfigManager();

                /**
                 * @brief 验证配置有效性
                 * @return 验证结果，成功返回空字符串
                 */
                std::string validate() const;
            };

            /**
             * @brief 构造函数
             * @param config 配置
             * @param mysql_pool MySQL连接池
             * @param redis_pool Redis连接池
             * @param thread_pool 线程池
             */
            UserRepository(const Config& config,
                          std::shared_ptr<common::database::MySQLPool> mysql_pool,
                          std::shared_ptr<common::database::RedisPool> redis_pool = nullptr,
                          std::shared_ptr<common::thread_pool::ThreadPool> thread_pool = nullptr);

            /**
             * @brief 析构函数
             */
            ~UserRepository();

            // ==================== 用户基础信息操作 ====================

            /**
             * @brief 创建用户
             * @param user_info 用户信息
             * @return 创建成功返回用户ID，失败返回0
             */
            int64_t createUser(const CoreUserInfo& user_info);

            /**
             * @brief 根据用户ID查找用户
             * @param user_id 用户ID
             * @param use_cache 是否使用缓存
             * @return 用户信息，未找到返回nullopt
             */
            std::optional<CoreUserInfo> findUserById(int64_t user_id, bool use_cache = true);

            /**
             * @brief 根据用户名查找用户
             * @param username 用户名
             * @param use_cache 是否使用缓存
             * @return 用户信息，未找到返回nullopt
             */
            std::optional<CoreUserInfo> findUserByUsername(const std::string& username, bool use_cache = true);

            /**
             * @brief 根据邮箱查找用户
             * @param email 邮箱
             * @param use_cache 是否使用缓存
             * @return 用户信息，未找到返回nullopt
             */
            std::optional<CoreUserInfo> findUserByEmail(const std::string& email, bool use_cache = true);

            /**
             * @brief 更新用户登录信息（仅更新登录相关字段，避免验证问题）
             * @param user_id 用户ID
             * @param login_attempts 登录尝试次数
             * @param locked_until 锁定截止时间
             * @param last_login_at 最后登录时间
             * @param last_login_ip 最后登录IP
             * @param online_status 在线状态
             * @return 更新成功返回true
             */
            bool updateUserLoginInfo(int64_t user_id, int login_attempts,
                                   std::optional<std::chrono::system_clock::time_point> locked_until,
                                   std::optional<std::chrono::system_clock::time_point> last_login_at,
                                   const std::string& last_login_ip,
                                   OnlineStatus online_status);

            /**
             * @brief 更新用户信息
             * @param user_info 用户信息
             * @return 更新成功返回true
             */
            bool updateUser(const CoreUserInfo& user_info);

            /**
             * @brief 删除用户（软删除）
             * @param user_id 用户ID
             * @return 删除成功返回true
             */
            bool deleteUser(int64_t user_id);

            /**
             * @brief 批量查询用户
             * @param user_ids 用户ID列表
             * @param use_cache 是否使用缓存
             * @return 用户信息列表
             */
            std::vector<CoreUserInfo> findUsersByIds(const std::vector<int64_t>& user_ids, bool use_cache = true);

            /**
             * @brief 条件查询用户
             * @param options 查询选项
             * @return 用户信息列表
             */
            std::vector<CoreUserInfo> findUsers(const QueryOptions& options);

            /**
             * @brief 统计用户数量
             * @param options 查询选项
             * @return 用户数量
             */
            int64_t countUsers(const QueryOptions& options);

            // ==================== 游戏用户数据操作 ====================

            /**
             * @brief 创建游戏用户数据
             * @param game_data 游戏用户数据
             * @return 创建成功返回true
             */
            bool createGameUserData(const GameUserData& game_data);

            /**
             * @brief 获取用户游戏数据
             * @param user_id 用户ID
             * @param game_type 游戏类型
             * @param use_cache 是否使用缓存
             * @return 游戏用户数据，未找到返回nullopt
             */
            std::optional<GameUserData> getUserGameData(int64_t user_id, GameType game_type, bool use_cache = true);

            /**
             * @brief 更新游戏用户数据
             * @param game_data 游戏用户数据
             * @return 更新成功返回true
             */
            bool updateGameUserData(const GameUserData& game_data);

            /**
             * @brief 获取用户所有游戏数据
             * @param user_id 用户ID
             * @param use_cache 是否使用缓存
             * @return 游戏用户数据列表
             */
            std::vector<GameUserData> getAllUserGameData(int64_t user_id, bool use_cache = true);

            /**
             * @brief 删除游戏用户数据
             * @param user_id 用户ID
             * @param game_type 游戏类型
             * @return 删除成功返回true
             */
            bool deleteGameUserData(int64_t user_id, GameType game_type);

            /**
             * @brief 批量更新游戏用户数据
             * @param game_data_list 游戏用户数据列表
             * @return 批量操作结果
             */
            BatchOperationResult batchUpdateGameUserData(const std::vector<GameUserData>& game_data_list);

            // ==================== 异步操作 ====================

            /**
             * @brief 异步创建用户
             * @param user_info 用户信息
             * @return Future对象，包含用户ID
             */
            std::future<int64_t> createUserAsync(const CoreUserInfo& user_info);

            /**
             * @brief 异步查找用户
             * @param user_id 用户ID
             * @param use_cache 是否使用缓存
             * @return Future对象，包含用户信息
             */
            std::future<std::optional<CoreUserInfo>> findUserByIdAsync(int64_t user_id, bool use_cache = true);

            /**
             * @brief 异步更新用户
             * @param user_info 用户信息
             * @return Future对象，包含更新结果
             */
            std::future<bool> updateUserAsync(const CoreUserInfo& user_info);

            /**
             * @brief 异步获取游戏数据
             * @param user_id 用户ID
             * @param game_type 游戏类型
             * @param use_cache 是否使用缓存
             * @return Future对象，包含游戏用户数据
             */
            std::future<std::optional<GameUserData>> getUserGameDataAsync(int64_t user_id, GameType game_type, bool use_cache = true);

            // ==================== 缓存管理 ====================

            /**
             * @brief 预热用户缓存
             * @param user_ids 用户ID列表
             * @return 预热成功的用户数量
             */
            int warmupUserCache(const std::vector<int64_t>& user_ids);

            /**
             * @brief 清除用户缓存
             * @param user_id 用户ID
             * @return 清除成功返回true
             */
            bool clearUserCache(int64_t user_id);

            /**
             * @brief 清除游戏数据缓存
             * @param user_id 用户ID
             * @param game_type 游戏类型
             * @return 清除成功返回true
             */
            bool clearGameDataCache(int64_t user_id, GameType game_type);

            /**
             * @brief 清除所有缓存
             * @return 清除成功返回true
             */
            bool clearAllCache();

            /**
             * @brief 获取缓存统计信息
             * @return 缓存统计信息
             */
            nlohmann::json getCacheStatistics();

            // ==================== 事务支持 ====================

            /**
             * @brief 开始事务
             * @return 事务成功开始返回true
             */
            bool beginTransaction();

            /**
             * @brief 提交事务
             * @return 事务提交成功返回true
             */
            bool commitTransaction();

            /**
             * @brief 回滚事务
             * @return 事务回滚成功返回true
             */
            bool rollbackTransaction();

            /**
             * @brief 执行事务
             * @param transaction_func 事务函数
             * @return 事务执行结果
             */
            template<typename Func>
            bool executeTransaction(Func&& transaction_func);

            // ==================== 统计和监控 ====================

            /**
             * @brief 获取统计信息
             * @return 统计信息JSON对象
             */
            nlohmann::json getStatistics() const;

            /**
             * @brief 重置统计信息
             */
            void resetStatistics();

                    /**
         * @brief 获取总用户数
         * @return 总注册用户数
         */
        int64_t getTotalUserCount() const;

        /**
         * @brief 获取健康状态
         * @return 健康状态信息
         */
        nlohmann::json getHealthStatus() const;

        private:
            Config config_;                                                     ///< 配置
            std::shared_ptr<common::database::MySQLPool> mysql_pool_;          ///< MySQL连接池
            std::shared_ptr<common::database::RedisPool> redis_pool_;          ///< Redis连接池
            std::shared_ptr<common::thread_pool::ThreadPool> thread_pool_;     ///< 线程池

            // 统计信息
            mutable std::atomic<uint64_t> queries_executed_{0};                ///< 执行的查询数量
            mutable std::atomic<uint64_t> cache_hits_{0};                      ///< 缓存命中次数
            mutable std::atomic<uint64_t> cache_misses_{0};                    ///< 缓存未命中次数
            mutable std::atomic<uint64_t> users_created_{0};                   ///< 创建的用户数量
            mutable std::atomic<uint64_t> users_updated_{0};                   ///< 更新的用户数量
            mutable std::atomic<uint64_t> game_data_operations_{0};            ///< 游戏数据操作次数

            // ==================== 内部方法 ====================

            /**
             * @brief 生成用户缓存键
             * @param user_id 用户ID
             * @return 缓存键
             */
            std::string generateUserCacheKey(int64_t user_id);

            /**
             * @brief 生成用户名缓存键
             * @param username 用户名
             * @return 缓存键
             */
            std::string generateUsernameCacheKey(const std::string& username);

            /**
             * @brief 生成邮箱缓存键
             * @param email 邮箱
             * @return 缓存键
             */
            std::string generateEmailCacheKey(const std::string& email);

            /**
             * @brief 生成游戏数据缓存键
             * @param user_id 用户ID
             * @param game_type 游戏类型
             * @return 缓存键
             */
            std::string generateGameDataCacheKey(int64_t user_id, GameType game_type);

            /**
             * @brief 从缓存获取用户信息
             * @param cache_key 缓存键
             * @return 用户信息，未找到返回nullopt
             */
            std::optional<CoreUserInfo> getUserFromCache(const std::string& cache_key);

            /**
             * @brief 将用户信息存入缓存
             * @param cache_key 缓存键
             * @param user_info 用户信息
             * @param ttl 缓存TTL
             * @return 存储成功返回true
             */
            bool setUserToCache(const std::string& cache_key, const CoreUserInfo& user_info, std::chrono::seconds ttl);

            /**
             * @brief 从缓存获取游戏数据
             * @param cache_key 缓存键
             * @return 游戏数据，未找到返回nullopt
             */
            std::optional<GameUserData> getGameDataFromCache(const std::string& cache_key);

            /**
             * @brief 将游戏数据存入缓存
             * @param cache_key 缓存键
             * @param game_data 游戏数据
             * @param ttl 缓存TTL
             * @return 存储成功返回true
             */
            bool setGameDataToCache(const std::string& cache_key, const GameUserData& game_data, std::chrono::seconds ttl);

            /**
             * @brief 从数据库查询用户
             * @param sql SQL语句
             * @param params 参数列表
             * @return 用户信息，未找到返回nullopt
             */
            std::optional<CoreUserInfo> queryUserFromDB(const std::string& sql, const std::vector<std::string>& params);

            /**
             * @brief 从数据库查询多个用户
             * @param sql SQL语句
             * @param params 参数列表
             * @return 用户信息列表
             */
            std::vector<CoreUserInfo> queryUsersFromDB(const std::string& sql, const std::vector<std::string>& params);

            /**
             * @brief 从数据库查询游戏数据
             * @param sql SQL语句
             * @param params 参数列表
             * @return 游戏数据，未找到返回nullopt
             */
            std::optional<GameUserData> queryGameDataFromDB(const std::string& sql, const std::vector<std::string>& params);

            /**
             * @brief 执行数据库更新操作
             * @param sql SQL语句
             * @param params 参数列表
             * @return 影响的行数
             */
            int executeUpdate(const std::string& sql, const std::vector<std::string>& params);

            /**
             * @brief 构建用户插入SQL
             * @param user_info 用户信息
             * @return SQL语句和参数
             */
            std::pair<std::string, std::vector<std::string>> buildUserInsertSQL(const CoreUserInfo& user_info);

            /**
             * @brief 构建用户更新SQL
             * @param user_info 用户信息
             * @return SQL语句和参数
             */
            std::pair<std::string, std::vector<std::string>> buildUserUpdateSQL(const CoreUserInfo& user_info);

            /**
             * @brief 从结果集构建用户信息
             * @param result_set 结果集
             * @return 用户信息
             */
            CoreUserInfo buildUserFromResultSet(sql::ResultSet* result_set);

            /**
             * @brief 从结果集构建游戏数据
             * @param result_set 结果集
             * @return 游戏数据
             */
            GameUserData buildGameDataFromResultSet(sql::ResultSet* result_set);

            /**
             * @brief 验证数据库连接
             * @return 连接有效返回true
             */
            bool validateDatabaseConnection();

            /**
             * @brief 验证缓存连接
             * @return 连接有效返回true
             */
            bool validateCacheConnection();

            /**
             * @brief 加载用户角色
             * @param user_info 用户信息
             */
            void loadUserRoles(CoreUserInfo& user_info);

            /**
             * @brief 加载用户元数据
             * @param user_info 用户信息
             */
            void loadUserMetadata(CoreUserInfo& user_info);

            /**
             * @brief 更新用户角色
             * @param user_info 用户信息
             */
            void updateUserRoles(const CoreUserInfo& user_info);

            /**
             * @brief 更新用户元数据
             * @param user_info 用户信息
             */
            void updateUserMetadata(const CoreUserInfo& user_info);

            /**
             * @brief 加载游戏用户自定义数据
             * @param game_data 游戏用户数据
             */
            void loadGameUserCustomData(GameUserData& game_data);

            /**
             * @brief 加载游戏用户成就
             * @param game_data 游戏用户数据
             */
            void loadGameUserAchievements(GameUserData& game_data);
        };

    } // namespace auth_service
} // namespace core_services

#endif //USER_REPOSITORY_H
